/**
 * Copyright (c) 2012, Ken Anderson, Brent Mucci
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the above copyright notice, 
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice, 
 *    this list of conditions and the following disclaimer in the documentation 
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 **/

#include <stdio.h> // NULL

#include "mcl_image.h"

using namespace mcl;

Image::Image() :
	m_width(0), m_height(0), m_pitch(0), m_pData(NULL)
{
}

Image::~Image() 
{
	if(m_pData != NULL)
	{
		delete[] m_pData;
		m_pData = NULL;
	}
}

bool Image::init(int w, int h)
{
	// Exit if already set.
	if(	
			m_width == w &&
			m_height == h &&
			m_pData != NULL
	)
	{
		return true;
	}

	m_width  = w;
	m_height = h;
	m_pitch  = m_width;
	
	if( m_pData != NULL )
	{
		delete[] m_pData;
		m_pData = NULL;
	}
	m_pData   = new unsigned char[m_width*m_height*4];

	return (m_pData != NULL);
}

bool Image::generateCheckerboard(int seed)
{
	if( m_width == 0 || m_height == 0 || m_pData == NULL )
		return false;
	
	unsigned int i, j, c;
	char * d = (char *)m_pData;
	for (i = 0; i < m_height; i++) 
	{
		for (j = 0; j < m_width; j++) 
		{
			c = (((((i+seed)&0x40)==0)^((j&0x40)==0)))*255;
			int index = i*m_width*4+j*4;
			d[index+0] = (char) c;
			d[index+1] = (char) c;
			d[index+2] = (char) c;
			d[index+3] = (char)0Xff; // ALPHA
		}
	}
	return true;
}

// The scanning of images are done from the bottom up when piped to the screen.
// Therefore the Y-axis of the image needs to be reversed to be displayed properly.
bool Image::flipY()
{
	if(m_pData != NULL)
	{
		unsigned int rowOffset = 0;
		unsigned int colOffset = 0;
		unsigned int tempRGBA;
		unsigned int * pData = (unsigned int*)m_pData;
		for(unsigned int row = 0; row < m_height / 2; row++) 
		{
			for(unsigned int col = 0; col < m_width; col++) 
			{
				const unsigned int index1 = rowOffset + colOffset;
				const unsigned int index2 = (m_height-1)*m_pitch-rowOffset+colOffset;
				tempRGBA = pData[index1];
				pData[index1] = pData[index2];
				pData[index2] = tempRGBA;

				colOffset += 1;
			}
			colOffset = 0;
			rowOffset += m_pitch;
		}
		return true;
	}
	return false;
}
